package com.justnow;


import java.util.HashMap;

/**
 * 参考链接：https://blog.csdn.net/qq_41231926/article/details/86173740
 * 双向链表，负责保存node，node个中有key,value,pre指针，next指针；
 *
 */
public class LRUCache {
    private class Node {
        private int key;
        private int value;
        private Node pre;
        private Node next;
        public Node() {

        }
        public Node(int key, int value) {
            this.key = key;
            this.value = value;
        }

    }
    private Node dummyHead = new Node(); //头结点
    private Node dummyTail = new Node(); //尾结点
    private int capacity;
    private int size;
    private HashMap<Integer, Node> hashMap = new HashMap<>();
    // 将结点添加到虚拟头节点之后
    public void add(Node node) {
        Node originHead = dummyHead.next;
        dummyHead.next = node;
        node.pre = dummyHead;
        originHead.pre = node;
    }

    // 删除某个结点
    public void del(Node node) {
        Node preNode = node.pre;
        Node nextNode = node.next;
        preNode.next = nextNode;
        nextNode.pre = preNode;
        node.pre = null;
        node.next = null;
    }

    public LRUCache(int capacity){
        this.dummyHead.next = dummyTail;
        dummyTail.pre = dummyHead;
        this.capacity = capacity;
        size = 0;
    }

    public int get(int key) {
        Node node = hashMap.get(key);
        if (node == null)
            return -1;
        del(node);
        add(node);//即将node放在最前面的位置
        return node.value;
    }

    public void put(int key, int value) {
        Node node = hashMap.get(key);
        if (null != node) {
            node.value = value;
            del(node);
            add(node);//访问了一次数据，将其方法链表的头部
        } else {
            if (size < capacity) {
                size++;
            } else {
                //插入时，双向链表已经满了，需要将尾部的删除
                Node delNode = dummyTail.pre;
                hashMap.remove(delNode.key);
                del(delNode);
            }
            Node newNode = new Node(key, value);
            add(newNode);
            hashMap.put(key, newNode);
        }
    }

    public static void main(String[] args) {
        LRUCache cache = new LRUCache(2);
        cache.put(1, 20);
    }
}

